package com.cunyu.listener;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.cunyu.util.MD5;
import org.apache.commons.lang.StringUtils;
import org.patchca.color.RandomColorFactory;
import org.patchca.service.Captcha;
import org.patchca.service.ConfigurableCaptchaService;
import org.patchca.text.renderer.BestFitTextRenderer;
import org.patchca.word.RandomWordFactory;

import com.alibaba.fastjson.JSON;

public class RequestContext {
	
	public final static Hashtable<String,HttpSession> uid_session = new Hashtable<String,HttpSession>();
	private static ConfigurableCaptchaService cs = new ConfigurableCaptchaService();
	public ThreadLocal<RequestContext> local = new ThreadLocal<RequestContext>();
	private HttpSession session;
	private HttpServletRequest req;
	private HttpServletResponse res;
	private Map<String, Cookie> cookies;
	private final static ThreadLocal<RequestContext> contexts = new ThreadLocal<RequestContext>();
	public long i = System.currentTimeMillis();
	public HttpSession getSession() {
		return session;
	}

	public HttpServletRequest getRequest() {
		return req;
	}
	
	public Map<String, String> getParameterMap() {
		Map<String, String[]> hm = req.getParameterMap();
		Map<String, String> parameterMap = new HashMap<String, String>();
		Iterator<String> ite = hm.keySet().iterator();
		while (ite.hasNext()) {
			String key = ite.next();
			String[] values =  hm.get(key);
			String pamValues = "";
			for (String value : values) {
				if (pamValues.length() > 0)
					pamValues += ",";
				pamValues += value.trim();
				parameterMap.put(key, pamValues);
			}
		}
		return parameterMap;
	}

	public HttpServletResponse getResponse() {
		return res;
	}

	public Map<String, Cookie> getCookies() {
		return cookies;
	}
	
	public Object getUser() {
		return session.getAttribute("user");
	}
	
	public void setUser(Object user){
		session.setAttribute("user",user);
	}
	
	public void redirect(String url) throws IOException{
		res.sendRedirect(res.encodeURL(url));
	}
	
	
	public String getIpAddr(){
		String ip = req.getHeader("X-REAL-IP");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
			ip = req.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
			ip = req.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
			ip = req.getRemoteAddr();
		}
		return ip;
	}
	
	
	public InputStream getCode(){
        // 颜色创建工厂,使用一定范围内的随机色  
		RandomColorFactory colorFactory = new RandomColorFactory();  
        cs.setColorFactory(colorFactory);  
          
        // 随机字体生成器  
//	        RandomFontFactory    fontFactory = new RandomFontFactory();  
//	        fontFactory.setMaxSize(32);  
//	        fontFactory.setMinSize(28);  
//	        cs.setFontFactory(fontFactory);  
          
        // 随机字符生成器,去除掉容易混淆的字母和数字,如o和0等  
        RandomWordFactory  wordFactory = new RandomWordFactory();  
        wordFactory.setCharacters("abcdefghkmnpqstwxyz23456789");  
        wordFactory.setMaxLength(5);  
        wordFactory.setMinLength(4);    //随机字数
        cs.setWordFactory(wordFactory);  
          
        // 文字渲染器设置  
        BestFitTextRenderer textRenderer = new BestFitTextRenderer();  
        textRenderer.setBottomMargin(3);  
        textRenderer.setTopMargin(3);  
        cs.setTextRenderer(textRenderer);  
          
        // 验证码图片的大小  
        //cs.setWidth(82);  
        //cs.setHeight(32); 
	    Captcha c =  cs.getCaptcha();
	    session.setAttribute("mcode", c.getChallenge());
	    BufferedImage img = c.getImage();
	    ByteArrayOutputStream out =  new ByteArrayOutputStream();
	    try {
			ImageIO.write(img, "png", out);
			return new ByteArrayInputStream(out.toByteArray());
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(out!=null)
				try {out.close();} catch (IOException e) {}
		}
	    return null;
	}
	
	
	public Cookie getCookie(String name) {
		return cookies.get(name);
	}

	/**
	 * 设置COOKIE
	 * 
	 * @param name
	 * @param value
	 * @param maxAge second
	 */
	public void setCookie(String name, String value, int maxAge) {
		setCookie(name, value, maxAge, true, false);
	}

	public void setSafeCookie(String name, String value, int maxAge){
		setCookie(name, value, maxAge, true, true);
	}
	/**
	 * 设置COOKIE
	 * 
	 * @param name
	 * @param value
	 * @param maxAge 
	 */
	public void setCookie(String name, String value, int maxAge, boolean all_sub_domain,boolean isHttpOnly) {
		Cookie cookie = new Cookie(name, value);
		cookie.setMaxAge(maxAge);
		cookie.setHttpOnly(isHttpOnly);
		if (all_sub_domain) {
			String serverName = req.getServerName();
			String domain = getDomainOfServerName(serverName);
			if (domain != null && domain.indexOf('.') != -1 && !domain.startsWith("127")) {
				cookie.setDomain('.' + domain);
			}
		}
		cookie.setPath("/");
		res.addCookie(cookie);
	}
	
	/**
	 * 获取用户访问URL中的根域名 例如: www.dlog.cn -> dlog.cn
	 * @param req
	 * @return
	 */
	public static String getDomainOfServerName(String host) {
		if (isIPAddr(host))
			return null;
		String[] names = host.split("\\.");
		int len = names.length;
		if (len == 1) {
			return null;
		}
		if (len == 3) {
			return makeup(names[len - 2], names[len - 1]);
		}
		if (len > 3) {
			String dp = names[len - 2];
			if (dp.equalsIgnoreCase("com") || dp.equalsIgnoreCase("gov") || dp.equalsIgnoreCase("net") || dp.equalsIgnoreCase("edu") || dp.equalsIgnoreCase("org"))
				return makeup(names[len - 3], names[len - 2], names[len - 1]);
			else
				return makeup(names[len - 2], names[len - 1]);
		}
		return host;
	}
	
	private static String makeup(String... ps) {
		StringBuilder s = new StringBuilder();
		for (int idx = 0; idx < ps.length; idx++) {
			if (idx > 0) {
				s.append('.');
			}
			s.append(ps[idx]);
		}
		return s.toString();
	}
	
	public static boolean isIPAddr(String addr) {
		if (StringUtils.isEmpty(addr))
			return false;
		String[] ips = addr.split("\\.");
		if (ips.length != 4)
			return false;
		try {
			int ipa = Integer.parseInt(ips[0]);
			int ipb = Integer.parseInt(ips[1]);
			int ipc = Integer.parseInt(ips[2]);
			int ipd = Integer.parseInt(ips[3]);
			return ipa >= 0 && ipa <= 255 && ipb >= 0 && ipb <= 255 && ipc >= 0 && ipc <= 255 && ipd >= 0 && ipd <= 255;
		} catch (Exception e) {
		}
		return false;
	}
	

	public void deleteCookie(String name, boolean all_sub_domain) {
		setCookie(name, null, 0, all_sub_domain,false);
	}
	
	
	public RequestContext(HttpServletRequest req, HttpServletResponse res) {
		this.req = req;
		this.res = res;
		this.session = req.getSession(); // req.getSession(false) 默认不创建session
		this.cookies = new HashMap<String, Cookie>();
		Cookie[] cookies = req.getCookies();
		if (cookies != null)
			for (Cookie ck : cookies) {
				this.cookies.put(ck.getName(), ck);
			}
	}

	public static RequestContext begin(HttpServletRequest req, HttpServletResponse res) {
		RequestContext rc = new RequestContext(req, res);
		contexts.set(rc);
		return rc;
	}

	public static RequestContext get() {
		return contexts.get();
	}
	
	public void end() {
		this.req = null;
		this.res = null;
		this.session = null;
		this.cookies = null;
		contexts.remove();
	}

	public String getURI(){
		return req.getRequestURI().toLowerCase();
	}
	
	public String getParamsStr(){
		Map<String,String> map = new HashMap<String,String>();
		Enumeration<String> keys = req.getParameterNames();
		while(keys.hasMoreElements()){
			String name = keys.nextElement();
			if(name.equals("password")){
				map.put(name, MD5.MD5Encode(req.getParameter(name)));
			}else{
				map.put(name, req.getParameter(name));
			}
		}
		return JSON.toJSONString(map);
	}
	
	/**
	 * 消除异地登录的session信息,并保存本地session
	 * 
	 * 
	 * @param uid
	 */
	public void removeOtherLoginInfo(String uid){
		//判断有没有异地登录
		if(uid_session.containsKey(uid)){
			HttpSession s = uid_session.remove(uid);
			uid_session.put(uid, session);
			if(s!=null){
				s.invalidate();
			}
		}else{
			uid_session.put(uid, session);
		}
	}

	/**
	 * 判断当前销毁的session是否是当前登录者的session	
	 * 用户session超时 或者 主动下线 则返回true	
	 * 被挤下线的 则返回false	
	 * @param uid
	 * @param sid
	 * @return  1.用户session超时 或者 主动下线 则返回true     2.被挤下线的 则返回false
	 */
	public static boolean isSameSession(String uid,String sid){
		HttpSession s = uid_session.get(uid);
		if(s!=null&&!sid.equals(s.getId())){
			return false;
		}
		uid_session.remove(uid);
		return true;
	}
	
	
	
	
}
